Assuring code integrity of embedded systems software at runtime is becoming a significant security issue for an embedded electronic device. An example of high volume electronic devices where it is beneficial to ensure the integrity of the software stored in memory are personal digital assistants (PDAs) and cell phones. In general, these devices use internal microprocessors to execute instructions in two stages: boot-time and runtime. A trusted computer system uses cryptographic software to authenticate each stage prior to its execution.
During boot-time, an embedded processor executes fundamental hardware and software initialization instructions (the boot code) stored in non-volatile memory such as electrically erasable read only memory (such as a flash non-volatile memory), read only memory (ROM), or electrically programmable read only memory (EPROM). The purpose of the boot code is to validate and configure the hardware and hardware related data in order to present a known execution environment and user interface for the system software. For trusted computer operation, the boot code also validates or authenticates the program application and operating system (OS) memory at boot-time to ensure that it contains the code that is expected and hence trusted. Once the boot-time instruction has checked for authenticity, the system control is passed to the validated OS/application execution image and enters the runtime mode.
During runtime, the processor executes code out of the OS/application image. The OS will typically establish a multi-process runtime execution environment and load any start-up or embedded applications in preparation for normal runtime processes. It is during this later time, when the runtime environment is fully established, that it is possible for untrusted user application code or downloaded dynamic code to be run and for memory corruption to occur on the original trusted and authenticated code, due to non-boot-time factors such as computer viruses or internal programming bugs. Furthermore, the OS/application program memory validated at boot-time could maliciously be replaced by a runtime memory, which is completely different from what is authenticated at boot-time. This is known as a “piggy back” attack, which poses a considerable security threat to embedded system software. Requiring physical access to the product platform, a runtime memory device is piggy-backed over the original validated memory device. It completely replaces the validated boot device after the boot process finishes and passes control to the external memory, hence creating a completely different, unchecked runtime environment.
Conventional methods of validating instruction codes in systems software only authenticate the instruction memory once. One-time validation is performed either by generating a one-way memory reference signature or asymmetric key digital signature using a cryptographic algorithm. Prior to execution, a message authentication code or a similar digital signature is generated on the instruction memory. If the generated result matches a pre-determined value stored elsewhere in the system or within the encrypted asymmetric digital signature, the instructions are permitted to execute. However, current solutions do not address the risk of tampering with the instruction memory contents after the initial authentication. During runtime, instruction codes are vulnerable to piggy-back or software attacks which will replace the authenticated instruction memory or data. Integrity of initially authenticated codes can be compromised by physical replacement of memory or diversion of processor to execute code from a memory range that was not originally authenticated. For example, a computer virus can remain dormant during boot-time and then cause an exception in the processor to make it execute a different set of instructions.
A large portion of the system software controlling an electronic device should not change during the course of operation of the device. Even though the system software is loaded into memory with high assurance by initial authentication, the probability of system degradation goes up after several million clock cycles and continued exposure to un-trusted code. If the system is corrupted, it cannot be trusted to perform self-check functions. In fact, the reference data/memory that is used to make these self-checks are security targets or vulnerabilities and examples of data that is security sensitive and should never change. Other security sensitive data could be configuration registers, which control internal data visibility external to an embedded device or OS sensitive data such as (interrupt service routine (ISR) addresses or specific memory management unit (MMU) page tables or specific file system data such as user and group identifiers and passwords.
Furthermore, many embedded systems such as cell phones and PDA's enter the boot mode only if they are disconnected from power sources. Therefore, the integrity of original instruction codes of an embedded device in the runtime mode confronts a gradually increasing risk as the device runs downloaded application programs and communicates with external devices. The magnitude of this risk is therefore especially significant in devices that do not normally get disconnected from their power sources and that do not reboot to authenticate until power failures occur. Moreover, operating systems and application software are stored in different regions of memory. The fact that the software is stored in different regions and the software may be received from a number of sources, some reputable, others that cannot be substantiated poses a long term tracking and security problem.
Accordingly, it is desirable to devise a memory checker for runtime security assurance of software that is loaded to memory during the boot-time. It would be of benefit if the memory checker was autonomous to ensure checks occur. It would be of further benefit if the device was energy efficient and did not significantly impact runtime system performance by requiring frequent bus accesses.